<?php
class ImageHelper
{
	const STRETCH = 0;
	const PAD = 1;
	const CROP = 2;
	const PASSTHROUGH = 3;
	const FIT = 4;

    public static function getInstance()
    {
        static $instance;
        if (!$instance) {
            $class = __CLASS__;
            $instance = new $class;
        }
        return $instance;
    }

    public static function export($source_file, $export_file, $target_width, $target_height, $resize_mode, $watermark, $quality = 85) 
    {
        try {
            self::__export($source_file, $export_file, $target_width, $target_height, $resize_mode, $watermark, $quality = 85);
        } catch (IIException $e) {
			error_log("ERROR CLASS:" . __CLASS__ . ", FUNCTION: " . __FUNCTION__ . ", LINE: " . __LINE__);
            error_log('ERROR - soure file(' . $source_file . ')');
            error_log('ERROR - IIException:');
			error_log($e->getMessage());
			error_log($e->getTraceAsString());
            return FALSE;
        } catch (ImagickException $e) {
			error_log("ERROR CLASS:" . __CLASS__ . ", FUNCTION: " . __FUNCTION__ . ", LINE: " . __LINE__);
            error_log('ERROR - soure file(' . $source_file . ')');
            error_log('ERROR - ImagickException:');
			error_log($e->getMessage());
			error_log($e->getTraceAsString());
			return FALSE;		
        }

        return TRUE;
	}

    private static function __export($source_file, $export_file, $target_width, $target_height, $resize_mode, $watermark, $quality = 85)
    {
    	$_this = self::getInstance();
        $imagick = new Imagick($source_file);

		switch ($resize_mode) {
            case self::STRETCH:
                $_this->__stretch($imagick, $target_width, $target_height);
                break;
            case self::PAD:
                $imagick = $_this->__pad($imagick, $target_width, $target_height);
				break;
            case self::CROP:
                $_this->__crop($imagick, $target_width, $target_height);
				break;
            case self::FIT:
                $_this->__fit($imagick, $target_width, $target_height);
				break;
			default:
				break;
		}
		
		if ($watermark) {
            $_this->__watermark($imagick, $watermark);
		}

		// Remove any properties
		$properties = $imagick->getImageProperties('*');
		foreach ($properties as $k => $v) {
			$ret = $imagick->setImageProperty($k, NULL);
		}

		// Remove any profiles
		$image_profiles = $imagick->getImageProfiles('*');
		foreach ($image_profiles as $k => $v) {
			$ret = $imagick->removeImageProfile($k);
		}

		$imagick->setImageCompressionQuality($quality);
		$imagick->writeImage($export_file);		
		$imagick->destroy(); 
		
		return TRUE;
    }

    private static function __stretch($imagick, $target_width, $target_height)
    {
        $imagick->resizeImage($target_width, $target_height, Imagick::FILTER_LANCZOS, TRUE);
    }

    private static function __pad($imagick, $target_width, $target_height)
    {
        $imagick->thumbnailImage($target_width, $target_height, TRUE);

        $offset_x = ($target_width - $imagick->getImageWidth()) / 2;
        $offset_y = ($target_height - $imagick->getImageHeight()) / 2;

        $export_imagick = new Imagick();
        $export_imagick->newImage($target_width, $target_height, 'black', 'jpg');
        $export_imagick->compositeImage($imagick, Imagick::COMPOSITE_DEFAULT, $offset_x, $offset_y);

        return $export_imagick;
    }

    private static function __crop($imagick, $target_width, $target_height)
    {
        $imagick->cropThumbnailImage($target_width, $target_height);
    }

    private static function __fit($imagick, $target_width, $target_height)
    {
        $imagick->thumbnailImage($target_width, $target_height, TRUE);
    }

    private static function __watermark($imagick, $watermark)
    {
        $watermark_imagick = new Imagick($watermark);
        
        if($imagick->getImageWidth() < $watermark_imagick->getImageWidth() || $imagick->getImageHeight() < $watermark_imagick->getImageHeight()) {
			throw new IIException("ERROR - Watermark: target size smaller than watermark size!");
        }
        
        //whatermark x,y offset checking
        $watermark_x = $imagick->getImageWidth() - $watermark_imagick->getImageWidth();
        $watermark_y = $imagick->getImageHeight() - $watermark_imagick->getImageHeight();
        
        $imagick->compositeImage($watermark_imagick, Imagick::COMPOSITE_DEFAULT, $watermark_x, $watermark_y);
    }
}
?>
